<!DOCTYPE html>






<html class="theme-next muse use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">







  <script src="/lib/pace/pace.min.js?v=1.0.2"></script>
  <link href="/lib/pace/pace-theme-minimal.min.css?v=1.0.2" rel="stylesheet">







<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">


















  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">



















































<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/css/main.css?v=5.1.3" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.3">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.3">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.3">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.3" color="#222">





  <meta name="keywords" content="Groovy,">










<meta name="description" content="变量定义groovy 是动态类型的语言，也就是说不需要指定变量的类型，类型是可以值来推导的。  不指定类型定义变量： i = 10 使用关键字`` def，虽不是必须的，但是为了代码清晰，还是建议使用 def 关键字定义变量def i = 10`  这里有个误区：def 关键字的出现时替代变量类型的占位符，如果你已经明确了变量的类型，就没必要使用 def，也就是说 def int i = 10 是">
<meta name="keywords" content="Groovy">
<meta property="og:type" content="article">
<meta property="og:title" content="groovy入门">
<meta property="og:url" content="https://zachaxy.github.io/2017/10/26/groovy入门/index.html">
<meta property="og:site_name" content="zachaxy">
<meta property="og:description" content="变量定义groovy 是动态类型的语言，也就是说不需要指定变量的类型，类型是可以值来推导的。  不指定类型定义变量： i = 10 使用关键字`` def，虽不是必须的，但是为了代码清晰，还是建议使用 def 关键字定义变量def i = 10`  这里有个误区：def 关键字的出现时替代变量类型的占位符，如果你已经明确了变量的类型，就没必要使用 def，也就是说 def int i = 10 是">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2019-09-01T11:13:24.300Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="groovy入门">
<meta name="twitter:description" content="变量定义groovy 是动态类型的语言，也就是说不需要指定变量的类型，类型是可以值来推导的。  不指定类型定义变量： i = 10 使用关键字`` def，虽不是必须的，但是为了代码清晰，还是建议使用 def 关键字定义变量def i = 10`  这里有个误区：def 关键字的出现时替代变量类型的占位符，如果你已经明确了变量的类型，就没必要使用 def，也就是说 def int i = 10 是">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Muse',
    version: '5.1.3',
    sidebar: {"position":"right","display":"hide","offset":12,"b2t":false,"scrollpercent":true,"onmobile":true},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: 'undefined',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://zachaxy.github.io/2017/10/26/groovy入门/">





  <title>groovy入门 | zachaxy</title>









</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">






  <div class="container sidebar-position-right page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">


    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">zachaxy</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>

        <h1 class="site-subtitle" itemprop="description">纵情向前！</h1>

  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">



    <ul id="menu" class="menu">


        <li class="menu-item menu-item-home">
          <a href="/" rel="section">

              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>

            首页
          </a>
        </li>


        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">

              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>

            标签
          </a>
        </li>


        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">

              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>

            归档
          </a>
        </li>


        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">

              <i class="menu-item-icon fa fa-fw fa-user"></i> <br>

            关于
          </a>
        </li>



        <li class="menu-item menu-item-search">

            <a href="javascript:;" class="popup-trigger">


              <i class="menu-item-icon fa fa-search fa-fw"></i> <br>

            搜索
          </a>
        </li>

    </ul>



    <div class="site-search">

  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>

</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">


  <div id="posts" class="posts-expand">








  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">



  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://zachaxy.github.io/2017/10/26/groovy入门/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="zachaxy">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="zachaxy">
    </span>


      <header class="post-header">



          <h2 class="post-title" itemprop="name headline">groovy入门</h2>


        <div class="post-meta">
          <span class="post-time">

              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>

                <span class="post-meta-item-text">发表于</span>

              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-10-26T22:16:20+08:00">
                2017-10-26
              </time>





          </span>













            <div class="post-wordcount">


                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>

                  <span class="post-meta-item-text">字数统计&#58;</span>

                <span title="字数统计">
                  1,604
                </span>





            </div>




        </div>
      </header>





    <div class="post-body" itemprop="articleBody">





        <h1 id="变量定义"><a href="#变量定义" class="headerlink" title="变量定义"></a>变量定义</h1><p>groovy 是动态类型的语言，也就是说不需要指定变量的类型，类型是可以值来推导的。</p>
<ul>
<li>不指定类型定义变量： <code>i = 10</code></li>
<li>使用关键字`` def<code>，虽不是必须的，但是为了代码清晰，还是建议使用 def 关键字定义变量</code>def i = 10`</li>
</ul>
<p>这里有个误区：def 关键字的出现时替代变量类型的占位符，如果你已经明确了变量的类型，就没必要使用 def，也就是说 <code>def int i = 10</code> 是没有必要的</p>
<h1 id="字符串"><a href="#字符串" class="headerlink" title="字符串"></a>字符串</h1><ul>
<li>单引号:单引号中的内容严格对应 Java 中的 String</li>
<li>双引号:和脚本语言类似，如果字符串中有$符的话，先对 $表达式进行求值</li>
<li>三引号:针对的是很长的字符串，只要在三引号之间，可以随意换行</li>
</ul>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> s1 = <span class="string">'hello'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> s2 = <span class="string">"string append $&#123;version + 1&#125;"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> s3 = <span class="string">'''随意</span></span><br><span class="line"><span class="string">换行</span></span><br><span class="line"><span class="string">打印</span></span><br><span class="line"><span class="string">'''</span></span><br></pre></td></tr></table></figure>

<p>字符串的长度：<code>s1.size()</code></p>
<p>字符串的访问：<code>s1[2]</code>   //被当做数组来处理；</p>
<p>或者  <code>s1.getAt(index)</code></p>
<p>字符串的重复：</p>
<p><code>s = s1*3</code>  // 代表是将 s1 拼接三次</p>
<h1 id="函数定义"><a href="#函数定义" class="headerlink" title="函数定义"></a>函数定义</h1><ul>
<li>参数可以不指定类型</li>
<li>方法体中可以不使用 return 来返回，这样默认的返回值就是最后一行语句的值，但是如果不指定 return，定义函数时必须要使用 def。</li>
<li>可以指明返回值类型,这样就可以省略 def 关键字；但是如果未指定返回值类型，那么定义函数时必须使用 def 关键字</li>
<li>默认参数：可以给参数定义默认值，但是要注意的是，如果要定义有默认值的参数，那么该参数必须在参数列表的末尾</li>
</ul>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> sum(<span class="keyword">int</span> a,<span class="keyword">int</span> b = <span class="number">0</span>)&#123;</span><br><span class="line">	<span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sum(<span class="number">1</span>,<span class="number">2</span>)</span><br><span class="line">sum(<span class="number">1</span>)</span><br></pre></td></tr></table></figure>

<h1 id="函数调用"><a href="#函数调用" class="headerlink" title="函数调用"></a>函数调用</h1><ul>
<li>调用时，可以不加括号，但这并不是一个好的习惯，因为如果一个函数是无参的，那么不带括号，很可能被误认为是属性的调用；同时在嵌套函数调用时，也容易出错（将参数设置为另一个方法调用的结果）</li>
<li>最好的一种形式是：能加括号都加括号；如果该方法只有一个参数，那么调用时加括号，如果有多个参数，则可以省略括号</li>
<li>特别注意：如果该函数没有参数，那么调用时，必须加括号；同时这个的参数个数要和闭包的参数个数区分开</li>
</ul>
<h1 id="Groovy-bean-对象"><a href="#Groovy-bean-对象" class="headerlink" title="Groovy bean 对象"></a>Groovy bean 对象</h1><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span>  <span class="title">Bean</span>&#123;</span></span><br><span class="line">    <span class="keyword">int</span> version</span><br><span class="line">    String name;</span><br><span class="line"></span><br><span class="line">    Bean(<span class="keyword">int</span> version,String name)&#123;</span><br><span class="line">        <span class="keyword">this</span>.version = version;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Bean bean1 = <span class="keyword">new</span> Bean(<span class="number">1</span>,<span class="string">"zx"</span>)</span><br><span class="line"></span><br><span class="line">println bean1.name</span><br></pre></td></tr></table></figure>

<p>上面定义的 Bean 对象，在其内部定义了两个成员变量 version 和 name，这样默认就会为我们生成其对应的 getter 和 setter 方法。而在外部访问该成员变量时，其实是调用对应的 getter 和 setter 方法。</p>
<h1 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h1><p>闭包和函数是类似的，是一个代码片段，可以定义一个引用指向这个闭包，这类似于 C 语言中的函数指针；</p>
<p>闭包还可以获取外部变量；与 Java 中的内部类不同的是，在闭包内不仅可以获取到外部变量，同时也可以将其修改，修改对外部是可见的。</p>
<p>与函数定义不同的是，闭包的参数是在方法体内定义的，以 -&gt; 分割，左侧为参数，右侧为方法体</p>
<p>闭包方法体内，最后一句为返回值。</p>
<p>闭包的默认参数：如果定义的闭包只有一个参数，那么可以在闭包内直接写方法体，使用 <code>$it</code> 来获取参数。</p>
<p>如果要定义一个没有参数的闭包，那么闭包内， -&gt; 左侧为空，则代表该闭包没有参数</p>
<p>Groovy 中的函数，可以用闭包作为参数；</p>
<h1 id="集合类"><a href="#集合类" class="headerlink" title="集合类"></a>集合类</h1><p>groovy 中的集合包含两种：list 和 map，其使用也很简单</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">list = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">list &lt;&lt; <span class="number">3</span></span><br><span class="line">println list.size();</span><br><span class="line"></span><br><span class="line">map = [<span class="string">name:</span><span class="string">"zx"</span>,<span class="string">age:</span><span class="number">25</span>];</span><br><span class="line">map.merry = <span class="literal">false</span>	<span class="comment">// 向 map 添加键值对</span></span><br><span class="line">println map.size()  <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>

<h1 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h1><ul>
<li>范围运算符(..)</li>
</ul>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//range 更像是一个数组，其长度为 6，其为从 5 到 10</span></span><br><span class="line"><span class="keyword">def</span> range = <span class="number">5.</span><span class="number">.10</span></span><br><span class="line"><span class="comment">//通过 get(index)来获取对应的值</span></span><br><span class="line">println range.get(<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 其它实例</span></span><br><span class="line"><span class="number">1</span> .. &lt;<span class="number">10</span>    <span class="comment">//  独占范围的示例</span></span><br><span class="line"><span class="string">'a'</span>..<span class="string">'x'</span>   <span class="comment">// 范围也可以由字符组成</span></span><br><span class="line"><span class="number">10.</span><span class="number">.1</span>     <span class="comment">// 范围也可以按降序排列</span></span><br><span class="line"><span class="string">'x'</span>..<span class="string">'a'</span> <span class="comment">// 范围也可以由字符组成并按降序排列。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 由此就有如下 foreach 的写法</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i <span class="keyword">in</span> <span class="number">1.</span><span class="number">.5</span>) &#123;</span><br><span class="line">	println(i);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>三目运算符(?:)</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// 假设有这样一个需求，如果 name 不为 null，那么就输出 name 的值，否则输出 Anonymous</span><br><span class="line">// 下面的三目运算符的写法，未免有些啰嗦</span><br><span class="line">displayName = name ? name : &apos;Anonymous&apos;</span><br><span class="line"></span><br><span class="line">// 下面是 groovy 中支持三目运算符的写法</span><br><span class="line">displayName = name ?: &apos;Anonymous&apos;</span><br></pre></td></tr></table></figure>

<ul>
<li>展开操作符(*.)</li>
</ul>
<p>应用于实现了 iterator 的对象中，一般是数组，集合，是 foreach 的缩写</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> technologies = [<span class="string">'Groovy'</span>,<span class="string">'Grails'</span>,<span class="string">'Gradle'</span>]</span><br><span class="line">technologies*.toUpperCase() <span class="comment">// = to technologies.collect &#123; it?.toUpperCase() &#125;</span></span><br></pre></td></tr></table></figure>

<ul>
<li>安全操作符(?.)</li>
</ul>
<p>可以有效的避免空指针</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// eg：get(1)返回的结果是 null，此时如果调用 user.username 会产生空指针异常</span></span><br><span class="line"><span class="comment">//而是用 ?. 如果 user 为空,那么 username 也为 空，不会产生空指针异常</span></span><br><span class="line"><span class="keyword">def</span> user = User.get(<span class="number">1</span>)</span><br><span class="line"><span class="keyword">def</span> username = user?.username</span><br></pre></td></tr></table></figure>

<h1 id="文件操作"><a href="#文件操作" class="headerlink" title="文件操作"></a>文件操作</h1><p>groovy 提供了比 Java 更为便捷的方法来操作文件，其<a href="http://www.groovy-lang.org/gdk.html" target="_blank" rel="noopener">API 文档参考</a></p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">File file = <span class="keyword">new</span> File(<span class="string">"E:/hello.txt"</span>)</span><br><span class="line"><span class="comment">//按行读文件 </span></span><br><span class="line">file.eachLine &#123;  </span><br><span class="line">   line -&gt; println <span class="string">"line : $line"</span>; </span><br><span class="line">&#125; </span><br><span class="line"></span><br><span class="line"><span class="comment">//读取文件的整个内容，是用 text 熟悉</span></span><br><span class="line">println  file.text</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取文件内同的大小，单位是字节</span></span><br><span class="line">println file.length()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 写入文件,内容为 hello world</span></span><br><span class="line">file.withWriter(<span class="string">'utf-8'</span>) &#123; </span><br><span class="line">	writer -&gt; writer.writeLine <span class="string">'Hello World'</span> </span><br><span class="line">&#125;  </span><br><span class="line"></span><br><span class="line"><span class="comment">//复制文件</span></span><br><span class="line"><span class="keyword">def</span> src = <span class="keyword">new</span> File(<span class="string">"E:/hello.txt"</span>)</span><br><span class="line"><span class="keyword">def</span> dst = <span class="keyword">new</span> File(<span class="string">"E:/hello1.txt"</span>)</span><br><span class="line">dst &lt;&lt; src.text</span><br><span class="line"></span><br><span class="line"><span class="comment">//递归显示目录及其子目录中的所有文件</span></span><br><span class="line">file.eachFileRecurse() &#123;</span><br><span class="line">	file -&gt; println file.getAbsolutePath()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><p><a href="http://groovy-lang.org/documentation.html" target="_blank" rel="noopener">官方手册</a><br><a href="https://learnxinyminutes.com/docs/groovy/" target="_blank" rel="noopener">Learn groovy in Y minutes</a><br><a href="http://www.jianshu.com/p/ba55dc163dfd" target="_blank" rel="noopener">使用 Groovy 开发之新特性</a><br><a href="http://blog.csdn.net/dabaoonline/article/details/50477090" target="_blank" rel="noopener">日积月累–Groovy 语言规范之操作符</a><br><a href="http://www.jianshu.com/p/2c17a50ff7f1" target="_blank" rel="noopener">Groovy 学习之-运行时元编程</a><br><a href="https://www.ibm.com/developerworks/cn/education/java/j-groovy/j-groovy.html#N1036D" target="_blank" rel="noopener">精通 Groovy</a></p>


    </div>









      <div>
        <ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者：</strong>
    zachaxy
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="https://zachaxy.github.io/2017/10/26/groovy入门/" title="groovy入门">https://zachaxy.github.io/2017/10/26/groovy入门/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>
    本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/" rel="external nofollow" target="_blank">CC BY-NC-SA 3.0</a> 许可协议。转载请注明出处！
  </li>
</ul>

      </div>


    <footer class="post-footer">

        <div class="post-tags">

            <a href="/tags/Groovy/" rel="tag"># Groovy</a>

        </div>







        <div class="post-nav">
          <div class="post-nav-next post-nav-item">

              <a href="/2017/10/20/Maven简介/" rel="next" title="Maven简介">
                <i class="fa fa-chevron-left"></i> Maven简介
              </a>

          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">

              <a href="/2017/11/07/卡特兰数简介/" rel="prev" title="卡特兰数简介">
                卡特兰数简介 <i class="fa fa-chevron-right"></i>
              </a>

          </div>
        </div>




    </footer>
  </div>



  </article>



    <div class="post-spread">

    </div>
  </div>


          </div>









        </div>



  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">

      <div id="sidebar-dimmer"></div>

    <div class="sidebar-inner">




        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>


      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">

              <img class="site-author-image" itemprop="image" src="/images/avatar.jpg" alt="zachaxy">

              <p class="site-author-name" itemprop="name">zachaxy</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">


              <div class="site-state-item site-state-posts">

                <a href="/archives">

                  <span class="site-state-item-count">64</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>







              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">12</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>


          </nav>



          <div class="links-of-author motion-element">


                <span class="links-of-author-item">
                  <a href="https://github.com/zachaxy" target="_blank" title="GitHub">

                      <i class="fa fa-fw fa-globe"></i>GitHub</a>
                </span>

                <span class="links-of-author-item">
                  <a href="https://weibo.com/3242765540" target="_blank" title="Weibo">

                      <i class="fa fa-fw fa-globe"></i>Weibo</a>
                </span>


          </div>









        </div>
      </section>


      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">






              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#变量定义"><span class="nav-number">1.</span> <span class="nav-text">变量定义</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#字符串"><span class="nav-number">2.</span> <span class="nav-text">字符串</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#函数定义"><span class="nav-number">3.</span> <span class="nav-text">函数定义</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#函数调用"><span class="nav-number">4.</span> <span class="nav-text">函数调用</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Groovy-bean-对象"><span class="nav-number">5.</span> <span class="nav-text">Groovy bean 对象</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#闭包"><span class="nav-number">6.</span> <span class="nav-text">闭包</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#集合类"><span class="nav-number">7.</span> <span class="nav-text">集合类</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#运算符"><span class="nav-number">8.</span> <span class="nav-text">运算符</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#文件操作"><span class="nav-number">9.</span> <span class="nav-text">文件操作</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#参考"><span class="nav-number">10.</span> <span class="nav-text">参考</span></a></li></ol></div>


          </div>
        </section>
      <!--/noindex-->




    </div>
  </aside>



      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">zachaxy</span>


    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>

      <span class="post-meta-item-text">站点文章字数总计&#58;</span>

    <span title="站点文章字数总计">147.9k</span>

</div>






  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Muse</a></div>













      </div>
    </footer>


      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>

          <span id="scrollpercent"><span>0</span>%</span>

      </div>




  </div>



<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>
























    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>




    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>




    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>




    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>




    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>




    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>






  <script type="text/javascript" src="/js/src/utils.js?v=5.1.3"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.3"></script>







  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.3"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.3"></script>






  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.3"></script>







































  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>

















  <script type="text/javascript" src="/js/src/js.cookie.js?v=5.1.3"></script>
  <script type="text/javascript" src="/js/src/scroll-cookie.js?v=5.1.3"></script>





</body>
</html>
